package cn.hg.solon.youcan.framework.provider;

import cn.dev33.satoken.stp.StpInterface;
import cn.hg.solon.youcan.common.constant.CacheConstants;
import cn.hg.solon.youcan.framework.cache.RedisCacheTagsService;
import cn.hg.solon.youcan.system.entity.Permission;
import cn.hg.solon.youcan.system.entity.Role;
import cn.hg.solon.youcan.system.service.PermissionService;
import cn.hg.solon.youcan.system.service.RoleService;
import cn.hg.solon.youcan.system.service.UserService;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.convert.ConvertUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import java.util.List;
import java.util.function.Supplier;

/**
 * SA-Token的权限验证接口扩展
 *
 * @author 胡高
 */
@Component // 打开此注解，保证此类被 solon 扫描，即可完成 sa-token 的自定义权限验证扩展
public class PermissionProvider implements StpInterface {

    @Inject
    private PermissionService permissionService;

    @Inject
    private UserService userService;

    @Inject
    private RoleService roleService;

    @Inject
    private RedisCacheTagsService cacheService;

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.framework.service.PermissionService#getPermissionList(java.lang.Object, java.lang.String)
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        return this.cacheService.getOrStoreTag("permission-list:" + loginId, List.class, CacheConstants.CACHE_SECONDS_ONE_DAY, new Supplier<List>() {
            @Override
            public List get() {
                if (ObjUtil.equals(Integer.valueOf(1), ConvertUtil.toInt(loginId))) {
                    return ListUtil.of("*:*:*");
                }

                List<? extends Permission> permissionList =
                        PermissionProvider.this.permissionService.listByUser(PermissionProvider.this.userService.get(ConvertUtil.toInt(loginId)));
                return CollUtil.getFieldValues(permissionList, "value", String.class);
            }
        }, CacheConstants.SYS_USER_TAG);

    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.framework.service.PermissionService#getRoleList(java.lang.Object, java.lang.String)
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        return this.cacheService.getOrStoreTag("role-list:" + loginId, List.class, CacheConstants.CACHE_SECONDS_ONE_DAY, new Supplier<List>() {
            @Override
            public List get() {
                if (ObjUtil.equals(Integer.valueOf(1), ConvertUtil.toInt(loginId))) {
                    return ListUtil.of("administrators");
                }
                List<? extends Role> roleList = PermissionProvider.this.roleService.listByUser(PermissionProvider.this.userService.get(ConvertUtil.toInt(loginType)));
                return CollUtil.getFieldValues(roleList, "code", String.class);
            }
        }, CacheConstants.SYS_USER_TAG);
    }

}
